﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

using Zorbo;
using Zorbo.Interface;

using Jurassic;
using Jurassic.Library;

using JScript = Javascript.Script;

namespace Javascript.Objects
{
    public class RangeBanned : Collection
    {
        IRangeBanned rangebans;

        [JSProperty(Name = "count", IsConfigurable = true)]
        public override int Count {
            get { return items.Count; }
        }

        public RangeBanned(JScript script, IRangeBanned rbans)
            : base(script, ((ClrFunction)script.Engine.Global["Collection"]).InstancePrototype) {

            this.rangebans = rbans;
            this.rangebans.CollectionChanged += RangeBans_Changed;

            this.items.AddRange(this.rangebans.Select((s) => s.ToRegExpInstance(script.Engine)));

            this.PopulateFunctions();
        }

        [JSFunction(Name = "add", IsEnumerable = true)]
        public bool Add(RegExpInstance regex) {
            return rangebans.Add(regex.Value);
        }

        [JSFunction(Name = "remove", IsEnumerable = true)]
        public bool Remove(RegExpInstance regex) {
            return rangebans.Remove(regex.Value);
        }

        [JSFunction(Name = "removeAt", IsEnumerable = true)]
        public bool RemoveAt(int index) {
            return rangebans.RemoveAt(index);
        }

        [JSFunction(Name = "clear", IsEnumerable = true)]
        public void Clear() {
            this.rangebans.Clear();
        }

        private void RangeBans_Changed(object sender, NotifyCollectionChangedEventArgs e) {

            if (e.Action == NotifyCollectionChangedAction.Add)
                this.items.Add(((Regex)e.NewItems[0]).ToRegExpInstance(script.Engine));

            else if (e.Action == NotifyCollectionChangedAction.Remove)
                this.items.RemoveAt(e.OldStartingIndex);

            else if (e.Action == NotifyCollectionChangedAction.Reset)
                this.items.Clear();
        }

        protected override string InternalClassName {
            get { return "RangeBanned"; }
        }

        public override IEnumerable<PropertyNameAndValue> Properties {
            get {
                for (int i = 0; i < items.Count; i++)
                    yield return new PropertyNameAndValue(i.ToString(), new PropertyDescriptor(items[i], PropertyAttributes.FullAccess));
            }
        }

        public override PropertyDescriptor GetOwnPropertyDescriptor(uint index) {

            if (index < items.Count)
                return new PropertyDescriptor(items[(int)index], PropertyAttributes.FullAccess);

            return new PropertyDescriptor(null, PropertyAttributes.Sealed);
        }
    }
}
